package ws.jonas.sybosc.db;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import ws.jonas.sybosc.gui.LogPanel;

public class DBConfig {
	public static final File CONFIG_FILE = new File(System.getProperty("user.home") + System.getProperty("file.separator") + "sybosc_config.xml");
	public static final String HOST_KEY = "host";
	public static final String VENDOR_KEY = "vendor";
	public static final String USER_KEY = "user";
	public static final String PASSWORD_KEY = "password";
	public static final String CONFIG_KEY = "config";

	private String host = "";
	private String vendor = "";
	private String user = "";
	private String password = "";

	public synchronized void copy(DBConfig c) {
		if (c != null) {
			host = c.host;
			password = c.password;
			user = c.user;
			vendor = c.vendor;
		} else {
			host = null;
			password = null;
			user = null;
			vendor = null;
		}
	}

	public synchronized String getHost() {
		return host;
	}
	public synchronized void setHost(String host) {
		this.host = host;
	}
	public synchronized String getVendor() {
		return vendor;
	}
	public synchronized void setVendor(String vendor) {
		this.vendor = vendor;
	}
	public synchronized String getUser() {
		return user;
	}
	public synchronized void setUser(String user) {
		this.user = user;
	}
	public synchronized String getPassword() {
		return password;
	}
	public synchronized void setPassword(String password) {
		this.password = password;
	}

	@Override
	public synchronized String toString() {
		return "DBConfig[ host=" + host + ", vendor=" + vendor + ", user=" + user + ", password=" + password +" ]";
	}

	public void readConfig() {
		if (!DBConfig.CONFIG_FILE.exists()) {
			return;
		}

		SAXParser parser = null;
		try {
			parser = SAXParserFactory.newInstance().newSAXParser();
		} catch (Exception e) {
			LogPanel.getInstance().println(e); //TODO: what is this?
		}

		DBConfig.ConfigParser handler = new DBConfig.ConfigParser(this);
		try {
			parser.parse(DBConfig.CONFIG_FILE, handler);
		} catch (Exception e) {
			LogPanel.getInstance().println("Error while reading config: " + e.getMessage());
		}
	}

	public void writeConfig() {
		File configFile = DBConfig.CONFIG_FILE;
		File backupFile = new File(configFile.getAbsolutePath() + ".bak");
		configFile.renameTo(backupFile);

		PrintWriter out = null;
		try {
			configFile.createNewFile();
			out = new PrintWriter(new BufferedWriter(new FileWriter(configFile)));

			out.println("<" + DBConfig.CONFIG_KEY + ">");

			String host = getHost();
			if (host != null) {
				out.println("\t<" + DBConfig.HOST_KEY + ">" + host + "</" + DBConfig.HOST_KEY + ">");
			}

			String vendor = getVendor();
			if (vendor != null) {
				out.println("\t<" + DBConfig.VENDOR_KEY + ">" + vendor + "</" + DBConfig.VENDOR_KEY + ">");
			}

			String user = getUser();
			if (user != null) {
				out.println("\t<" + DBConfig.USER_KEY + ">" + user + "</" + DBConfig.USER_KEY + ">");
			}

			String password = getPassword();
			if (password != null) {
				out.println("\t<" + DBConfig.PASSWORD_KEY + ">" + password + "</" + DBConfig.PASSWORD_KEY + ">");
			}

			out.println("</" + DBConfig.CONFIG_KEY + ">");

			if (backupFile != null) {
				backupFile.delete();
			}
		} catch (IOException e) {
			//Backup file will not be deleted
			LogPanel.getInstance().println(e);
		} finally {
			if (out != null) {
				out.close();
			}
		}
	}

	private class ConfigParser extends DefaultHandler {
		private String currentElement;
		private final DBConfig config;

		public ConfigParser(DBConfig config) {
			this.config = config;
		}

		@Override
		public void startElement(String uri, String localName, String qName, Attributes attributes) {
			currentElement = qName;
		}

		@Override
		public void characters(char[] ch, int start, int length) throws SAXException {
			String data = new String(ch, start, length).trim();
			if (data != null && !data.equals("")) {
				if (currentElement.equals(DBConfig.HOST_KEY)) {
					config.setHost(data);
				} else if (currentElement.equals(DBConfig.VENDOR_KEY)) {
					config.setVendor(data);
				} else if (currentElement.equals(DBConfig.USER_KEY)) {
					config.setUser(data);
				} else if (currentElement.equals(DBConfig.PASSWORD_KEY)) {
					config.setPassword(data);
				} else {
					LogPanel.getInstance().println("Unknown config key: " + currentElement + ", data=" + data);
				}
			}
		}
	}
}
